using System;
using System.Collections.Generic;
using System.Data;
using System.Data.Common;
using System.Text.Json;
using System.Threading.Tasks;
using SeataNet.Core.Common;
using SeataNet.Core.Context;
using SeataNet.Core.Exceptions;
using SeataNet.Core.Model;
using SeataNet.Core.RPC;
using SeataNet.Core.Transaction;
using Microsoft.Extensions.Logging;
using SeataNet.Core.Protocol;

namespace SeataNet.Core.XA
{
    /// <summary>
    /// XA事务管理器接口
    /// </summary>
    public interface IXaTransactionManager : ITransactionManager
    {

        /// <summary>
        /// 注册XA分支事务
        /// </summary>
        /// <param name="xid">全局事务ID</param>
        /// <param name="branchType">分支类型</param>
        /// <param name="resourceId">资源ID</param>
        /// <param name="applicationData">应用数据</param>
        /// <returns>分支结果</returns>
        Task<BranchResult> BranchRegisterAsync(string xid, BranchType branchType, string resourceId, string? applicationData = null);

        /// <summary>
        /// 报告XA分支状态
        /// </summary>
        /// <param name="xid">全局事务ID</param>
        /// <param name="branchId">分支ID</param>
        /// <param name="status">分支状态</param>
        /// <param name="applicationData">应用数据</param>
        /// <returns>报告结果</returns>
        Task<bool> BranchReportAsync(string xid, long branchId, BranchStatus status, string? applicationData = null);

        /// <summary>
        /// 获取XA分支状态
        /// </summary>
        /// <param name="xid">全局事务ID</param>
        /// <param name="branchId">分支ID</param>
        /// <returns>分支状态</returns>
        Task<BranchStatus> GetBranchStatusAsync(string xid, long branchId);

        /// <summary>
        /// 创建XA连接
        /// </summary>
        /// <param name="connection">原始数据库连接</param>
        /// <param name="xid">全局事务ID</param>
        /// <returns>XA连接</returns>
        DbConnection CreateXaConnection(DbConnection connection, string xid);
    }

    /// <summary>
    /// 默认XA事务管理器实现
    /// </summary>
    public class DefaultXaTransactionManager : IXaTransactionManager
    {
        private readonly ILogger<DefaultXaTransactionManager> _logger;
        private readonly ITransactionManager _transactionManager;
        private readonly IResourceManager _resourceManager;
        private readonly ITransactionIdGenerator _transactionIdGenerator;
        private readonly Dictionary<string, XaConnection> _xaConnections = new Dictionary<string, XaConnection>();
        private readonly Dictionary<string, XaTransactionContext> _xaTransactions = new Dictionary<string, XaTransactionContext>();

        public DefaultXaTransactionManager(
            ILogger<DefaultXaTransactionManager> logger,
            ITransactionManager transactionManager,
            IResourceManager resourceManager,
            ITransactionIdGenerator transactionIdGenerator)
        {
            _logger = logger ?? throw new ArgumentNullException(nameof(logger));
            _transactionManager = transactionManager ?? throw new ArgumentNullException(nameof(transactionManager));
            _resourceManager = resourceManager ?? throw new ArgumentNullException(nameof(resourceManager));
            _transactionIdGenerator = transactionIdGenerator ?? throw new ArgumentNullException(nameof(transactionIdGenerator));
        }

        public Task<string> BeginAsync(int timeout = 60000, string? name = null)
        {
            _logger.LogInformation("开始XA全局事务，超时时间: {timeout}ms", timeout);
            
            var xid = _transactionIdGenerator.GenerateTransactionId();
            
            // 创建XA事务上下文
            var xaContext = new XaTransactionContext
            {
                Xid = xid,
                Status = XaTransactionStatus.Active,
                Timeout = timeout,
                BeginTime = DateTime.UtcNow,
                Branches = new List<XaBranchContext>()
            };
            
            // 将XA上下文存储到根上下文中
            RootContext.Bind(xaContext);
            
            return Task.FromResult(xid);
        }

        public async Task<bool> CommitAsync(string xid)
        {
            _logger.LogInformation("提交XA全局事务: {xid}", xid);
            
            // 获取XA事务上下文
            var xaContext = RootContext.GetXaTransactionContext();
            if (xaContext == null || xaContext.Xid != xid)
            {
                _logger.LogWarning("未找到XA事务上下文: {xid}", xid);
                return false;
            }
            
            try
            {
                // 提交所有XA分支
                foreach (var branch in xaContext.Branches)
                {
                    if (branch.Status == XaBranchStatus.Prepared)
                    {
                        await CommitBranchAsync(branch);
                    }
                }
                
                // 使用底层事务管理器提交全局事务
                var result = await _transactionManager.CommitAsync(xid);
                
                // 更新XA上下文状态
                xaContext.Status = XaTransactionStatus.Committed;
                xaContext.EndTime = DateTime.UtcNow;
                
                // 清理XA连接
                CleanupXaConnections(xid);
                
                return result;
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "提交XA事务失败: {xid}", xid);
                xaContext.Status = XaTransactionStatus.Failed;
                throw;
            }
            finally
            {
                // 清理上下文
                RootContext.Unbind();
            }
        }

        public async Task<bool> RollbackAsync(string xid)
        {
            _logger.LogInformation("回滚XA全局事务: {xid}", xid);
            
            // 获取XA事务上下文
            var xaContext = RootContext.GetXaTransactionContext();
            if (xaContext == null || xaContext.Xid != xid)
            {
                _logger.LogWarning("未找到XA事务上下文: {xid}", xid);
                return false;
            }
            
            try
            {
                // 回滚所有XA分支
                foreach (var branch in xaContext.Branches)
                {
                    if (branch.Status == XaBranchStatus.Prepared || branch.Status == XaBranchStatus.Committed)
                    {
                        await RollbackBranchAsync(branch);
                    }
                }
                
                // 使用底层事务管理器回滚全局事务
                var result = await _transactionManager.RollbackAsync(xid);
                
                // 更新XA上下文状态
                xaContext.Status = XaTransactionStatus.RolledBack;
                xaContext.EndTime = DateTime.UtcNow;
                
                // 清理XA连接
                CleanupXaConnections(xid);
                
                return result;
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "回滚XA事务失败: {xid}", xid);
                xaContext.Status = XaTransactionStatus.Failed;
                throw;
            }
            finally
            {
                // 清理上下文
                RootContext.Unbind();
            }
        }

        public async Task<int> GetStatusAsync(string xid)
        {
            // 使用底层事务管理器获取状态
            return await _transactionManager.GetStatusAsync(xid);
        }

        public async Task<GlobalTransactionContext?> GetGlobalTransactionAsync(string xid)
        {
            // 使用底层事务管理器获取全局事务上下文
            var context = await _transactionManager.GetGlobalTransactionAsync(xid);
            
            // 获取XA事务上下文
            var xaContext = RootContext.GetXaTransactionContext();
            if (xaContext != null && xaContext.Xid == xid)
            {
                // 如果找到XA上下文，将其附加到全局事务上下文中
                if (context != null)
                {
                    // 创建一个新的上下文，确保包含XA上下文信息
                    var newContext = new GlobalTransactionContext
                    {
                        Xid = context.Xid,
                        Status = context.Status,
                        ApplicationId = context.ApplicationId,
                        TransactionServiceGroup = context.TransactionServiceGroup,
                        TransactionName = context.TransactionName,
                        Timeout = context.Timeout,
                        BeginTime = context.BeginTime,
                        ApplicationData = JsonSerializer.Serialize(new { XaContext = xaContext })
                    };
                    
                    return newContext;
                }
            }
            
            return context;
        }

        // 同步方法实现
        public string Begin(string? transactionName = null, int timeout = 60000)
        {
            var xid = _transactionIdGenerator.GenerateTransactionId();
            
            // 创建XA事务上下文
            var xaContext = new XaTransactionContext
            {
                Xid = xid,
                Status = XaTransactionStatus.Active,
                Timeout = timeout,
                BeginTime = DateTime.UtcNow,
                Branches = new List<XaBranchContext>()
            };
            
            // 将XA上下文存储到根上下文中
            RootContext.Bind(xaContext);
            
            return xid;
        }

        public GlobalCommitResponse Commit(string xid)
        {
            // 使用底层事务管理器提交全局事务
            return _transactionManager.Commit(xid);
        }

        public GlobalRollbackResponse Rollback(string xid)
        {
            // 使用底层事务管理器回滚全局事务
            return _transactionManager.Rollback(xid);
        }

        public GlobalStatus GetStatus(string xid)
        {
            // 使用底层事务管理器获取状态
            return _transactionManager.GetStatus(xid);
        }

        public GlobalReportResponse GetGlobalReport(string xid)
        {
            // 使用底层事务管理器获取全局事务报告
            return _transactionManager.GetGlobalReport(xid);
        }



        public async Task<BranchResult> BranchRegisterAsync(string xid, BranchType branchType, string resourceId, string? applicationData = null)
        {
            _logger.LogInformation("注册XA分支事务: xid={xid}, branchType={branchType}, resourceId={resourceId}", 
                xid, branchType, resourceId);
            
            // 使用底层资源管理器注册分支
            var branchId = await _resourceManager.BranchRegisterAsync(branchType.ToString(), xid, resourceId, null, applicationData);
            
            // 获取XA事务上下文
            var xaContext = RootContext.GetXaTransactionContext();
            if (xaContext != null)
            {
                // 创建XA分支上下文
                var xaBranch = new XaBranchContext
                {
                    BranchId = branchId,
                    ResourceId = resourceId,
                    BranchType = branchType,
                    Status = XaBranchStatus.Active,
                    RegisterTime = DateTime.UtcNow
                };
                
                // 添加到XA上下文
                xaContext.Branches.Add(xaBranch);
            }

            return new BranchResult
            {
                BranchId = branchId,
                Success = true
            };
        }

        public async Task<bool> BranchReportAsync(string xid, long branchId, BranchStatus status, string? applicationData = null)
        {
            _logger.LogInformation("报告XA分支状态: xid={xid}, branchId={branchId}, status={status}", 
                xid, branchId, status);
            
            // 使用底层资源管理器报告分支状态
            var result = await _resourceManager.BranchReportAsync(xid, branchId, (int)status, applicationData);
            
            // 更新XA上下文中的分支状态
            var xaContext = RootContext.GetXaTransactionContext();
            if (xaContext != null)
            {
                var xaBranch = xaContext.Branches.Find(b => b.BranchId == branchId);
                if (xaBranch != null)
                {
                    xaBranch.Status = MapToXaBranchStatus(status);
                    xaBranch.ReportTime = DateTime.UtcNow;
                }
            }
            
            return result;
        }

        public async Task<BranchStatus> GetBranchStatusAsync(string xid, long branchId)
        {
            _logger.LogInformation("获取XA分支状态: xid={xid}, branchId={branchId}", xid, branchId);
            
            // 从XA上下文中获取分支状态
            var xaContext = RootContext.GetXaTransactionContext();
            if (xaContext != null)
            {
                var xaBranch = xaContext.Branches.Find(b => b.BranchId == branchId);
                if (xaBranch != null)
                {
                    return MapFromXaBranchStatus(xaBranch.Status);
                }
            }
            
            // 如果在XA上下文中找不到，返回默认状态
            return BranchStatus.Unknown;
        }

        public DbConnection CreateXaConnection(DbConnection connection, string xid)
        {
            if (connection == null)
                throw new ArgumentNullException(nameof(connection));
            
            if (string.IsNullOrEmpty(xid))
                throw new ArgumentException("XID不能为空", nameof(xid));
            
            _logger.LogInformation("创建XA连接: xid={xid}, connection={connection}", xid, connection.GetType().Name);
            
            // 创建XA连接
            var xaConnection = new XaConnection(connection, xid);
            
            // 存储XA连接
            var key = $"{xid}_{connection.GetHashCode()}";
            _xaConnections[key] = xaConnection;
            
            return xaConnection;
        }

        private async Task CommitBranchAsync(XaBranchContext branch)
        {
            _logger.LogInformation("提交XA分支: branchId={branchId}, resourceId={resourceId}", 
                branch.BranchId, branch.ResourceId);
            
            try
            {
                // 获取XA连接
                var xaConnection = GetXaConnection(branch.BranchId);
                if (xaConnection != null)
                {
                    // 提交XA分支
                    await xaConnection.CommitAsync();
                    branch.Status = XaBranchStatus.Committed;
                    branch.CommitTime = DateTime.UtcNow;
                }
                else
                {
                    _logger.LogWarning("未找到XA分支对应的连接: branchId={branchId}", branch.BranchId);
                }
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "提交XA分支失败: branchId={branchId}", branch.BranchId);
                branch.Status = XaBranchStatus.Failed;
                throw;
            }
        }

        private async Task RollbackBranchAsync(XaBranchContext branch)
        {
            _logger.LogInformation("回滚XA分支: branchId={branchId}, resourceId={resourceId}", 
                branch.BranchId, branch.ResourceId);
            
            try
            {
                // 获取XA连接
                var xaConnection = GetXaConnection(branch.BranchId);
                if (xaConnection != null)
                {
                    // 回滚XA分支
                    await xaConnection.RollbackAsync();
                    branch.Status = XaBranchStatus.RolledBack;
                    branch.RollbackTime = DateTime.UtcNow;
                }
                else
                {
                    _logger.LogWarning("未找到XA分支对应的连接: branchId={branchId}", branch.BranchId);
                }
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "回滚XA分支失败: branchId={branchId}", branch.BranchId);
                branch.Status = XaBranchStatus.Failed;
                throw;
            }
        }

        private XaConnection GetXaConnection(long branchId)
        {
            // 根据分支ID查找对应的XA连接
            foreach (var kvp in _xaConnections)
            {
                if (kvp.Value.BranchId == branchId)
                {
                    return kvp.Value;
                }
            }
            return null;
        }

        private void CleanupXaConnections(string xid)
        {
            // 清理指定XID的所有XA连接
            var keysToRemove = new List<string>();
            foreach (var kvp in _xaConnections)
            {
                if (kvp.Value.Xid == xid)
                {
                    kvp.Value.Dispose();
                    keysToRemove.Add(kvp.Key);
                }
            }
            
            foreach (var key in keysToRemove)
            {
                _xaConnections.Remove(key);
            }
        }

        private XaBranchStatus MapToXaBranchStatus(BranchStatus status)
        {
            return status switch
            {
                BranchStatus.PhaseOneDone => XaBranchStatus.Prepared,
                BranchStatus.PhaseOneFailed => XaBranchStatus.Failed,
                BranchStatus.PhaseTwoCommitted => XaBranchStatus.Committed,
                BranchStatus.PhaseTwoRollbacked => XaBranchStatus.RolledBack,
                BranchStatus.PhaseTwoRollbackFailedRetryable => XaBranchStatus.RollbackFailedRetryable,
                BranchStatus.PhaseTwoRollbackFailedUnretryable => XaBranchStatus.RollbackFailedUnretryable,
                _ => XaBranchStatus.Unknown
            };
        }

        private BranchStatus MapFromXaBranchStatus(XaBranchStatus status)
        {
            return status switch
            {
                XaBranchStatus.Active => BranchStatus.Unknown,
                XaBranchStatus.Prepared => BranchStatus.PhaseOneDone,
                XaBranchStatus.Committed => BranchStatus.PhaseTwoCommitted,
                XaBranchStatus.RolledBack => BranchStatus.PhaseTwoRollbacked,
                XaBranchStatus.Failed => BranchStatus.PhaseOneFailed,
                XaBranchStatus.RollbackFailedRetryable => BranchStatus.PhaseTwoRollbackFailedRetryable,
                XaBranchStatus.RollbackFailedUnretryable => BranchStatus.PhaseTwoRollbackFailedUnretryable,
                _ => BranchStatus.Unknown
            };
        }

        public async Task<long> RegisterBranchAsync(string xid, string resourceId, string lockKey)
        {
            try
            {
                _logger.LogDebug("Registering XA branch: XID={Xid}, ResourceId={ResourceId}", xid, resourceId);

                // 创建分支事务上下文
                var branchId = GenerateBranchId();
                var branchContext = new XaBranchContext
                {
                    BranchId = branchId,
                    ResourceId = resourceId,
                    Status = XaBranchStatus.Active,
                    RegisterTime = DateTime.UtcNow
                };

                // 将分支添加到全局事务
                if (_xaTransactions.TryGetValue(xid, out var transaction))
                {
                    transaction.Branches.Add(branchContext);
                }

                _logger.LogInformation("XA branch registered: XID={Xid}, BranchId={BranchId}", xid, branchId);
                return branchId;
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "Failed to register XA branch: XID={Xid}", xid);
                throw;
            }
        }

        public async Task ReportBranchStatusAsync(string xid, long branchId, BranchStatus status)
        {
            try
            {
                _logger.LogDebug("Reporting XA branch status: XID={Xid}, BranchId={BranchId}, Status={Status}",
                    xid, branchId, status);

                // 更新分支状态
                if (_xaTransactions.TryGetValue(xid, out var transaction))
                {
                    var branch = transaction.Branches.FirstOrDefault(b => b.BranchId == branchId);
                    if (branch != null)
                    {
                        branch.Status = MapToXaBranchStatus(status);
                    }
                }

                await Task.CompletedTask;
                _logger.LogInformation("XA branch status reported: XID={Xid}, BranchId={BranchId}", xid, branchId);
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "Failed to report XA branch status: XID={Xid}, BranchId={BranchId}",
                    xid, branchId);
                throw;
            }
        }

        private long GenerateBranchId()
        {
            return DateTime.UtcNow.Ticks;
        }
    }

    /// <summary>
    /// XA事务上下文
    /// </summary>
    public class XaTransactionContext
    {
        /// <summary>
        /// 全局事务ID
        /// </summary>
        public string Xid { get; set; }

        /// <summary>
        /// 事务状态
        /// </summary>
        public XaTransactionStatus Status { get; set; }

        /// <summary>
        /// 超时时间（毫秒）
        /// </summary>
        public int Timeout { get; set; }

        /// <summary>
        /// 开始时间
        /// </summary>
        public DateTime BeginTime { get; set; }

        /// <summary>
        /// 结束时间
        /// </summary>
        public DateTime? EndTime { get; set; }

        /// <summary>
        /// 分支事务列表
        /// </summary>
        public List<XaBranchContext> Branches { get; set; }
    }

    /// <summary>
    /// XA分支事务上下文
    /// </summary>
    public class XaBranchContext
    {
        /// <summary>
        /// 分支ID
        /// </summary>
        public long BranchId { get; set; }

        /// <summary>
        /// 资源ID
        /// </summary>
        public string ResourceId { get; set; }

        /// <summary>
        /// 分支类型
        /// </summary>
        public BranchType BranchType { get; set; }

        /// <summary>
        /// 分支状态
        /// </summary>
        public XaBranchStatus Status { get; set; }

        /// <summary>
        /// 注册时间
        /// </summary>
        public DateTime RegisterTime { get; set; }

        /// <summary>
        /// 准备时间
        /// </summary>
        public DateTime? PrepareTime { get; set; }

        /// <summary>
        /// 提交时间
        /// </summary>
        public DateTime? CommitTime { get; set; }

        /// <summary>
        /// 回滚时间
        /// </summary>
        public DateTime? RollbackTime { get; set; }

        /// <summary>
        /// 报告时间
        /// </summary>
        public DateTime? ReportTime { get; set; }
    }

    /// <summary>
    /// XA事务状态枚举
    /// </summary>
    public enum XaTransactionStatus
    {
        /// <summary>
        /// 未知状态
        /// </summary>
        Unknown,

        /// <summary>
        /// 活动状态
        /// </summary>
        Active,

        /// <summary>
        /// 准备中
        /// </summary>
        Preparing,

        /// <summary>
        /// 已准备
        /// </summary>
        Prepared,

        /// <summary>
        /// 已提交
        /// </summary>
        Committed,

        /// <summary>
        /// 已回滚
        /// </summary>
        RolledBack,

        /// <summary>
        /// 失败
        /// </summary>
        Failed,

        /// <summary>
        /// 超时
        /// </summary>
        Timeout
    }

    /// <summary>
    /// XA分支状态枚举
    /// </summary>
    public enum XaBranchStatus
    {
        /// <summary>
        /// 未知状态
        /// </summary>
        Unknown,

        /// <summary>
        /// 活动状态
        /// </summary>
        Active,

        /// <summary>
        /// 已准备
        /// </summary>
        Prepared,

        /// <summary>
        /// 已提交
        /// </summary>
        Committed,

        /// <summary>
        /// 已回滚
        /// </summary>
        RolledBack,

        /// <summary>
        /// 失败
        /// </summary>
        Failed,

        /// <summary>
        /// 回滚失败可重试
        /// </summary>
        RollbackFailedRetryable,

        /// <summary>
        /// 回滚失败不可重试
        /// </summary>
        RollbackFailedUnretryable
    }
}